package model

import (
	"time"

	"github.com/hwcer/cosgo/schema"
	"github.com/hwcer/cosgo/values"
	"github.com/hwcer/cosmo/update"
	"github.com/hwcer/logger"
	"github.com/hwcer/updater"
	"github.com/hwcer/updater/dataset"
	"github.com/hwcer/updater/operator"
	"github.com/hwcer/yyds/errors"
)

func init() {
	Register(&Active{})
}

// Active 运营活动
type Active struct {
	Model  `bson:"inline"`
	Update int64         `bson:"update" json:"update"  index:"name:_idx_uid_primary,Sort:desc,Priority:100" ` //最后更新时间
	Attach values.Attach `json:"attach" bson:"attach"`                                                        //数据
	Expire int64         `json:"expire" bson:"expire"`                                                        //过期时间
}

func (this *Active) Get(k string) (any, bool) {
	switch k {
	case "Attach", "attach":
		return this.Attach, true
	case "Expire", "expire":
		return this.Expire, true
	case "Update", "update":
		return this.Update, true
	default:
		return this.Model.Get(k)
	}
}

// Set 更新器
func (this *Active) Set(k string, v any) (any, bool) {
	switch k {
	case "Attach", "attach":
		if err := this.Marshal(v); err != nil {
			logger.Alert("Active set attach error,value:%v  err:%v", v, err)
			return nil, false
		} else {
			return this.Attach, true
		}
	case "Expire", "expire":
		this.Expire = v.(int64)
	case "Update", "update":
		this.Update = v.(int64)
	default:
		return this.Model.Set(k, v)
	}
	return v, true
}
func (this *Active) Marshal(v any) error {
	return this.Attach.Marshal(v)
}
func (this *Active) Unmarshal(v any) error {
	return this.Attach.Unmarshal(v)
}

func (this *Active) Copy() *Active {
	i := this.Clone()
	return i.(*Active)
}

// ----------------- 作为MODEL方法--------------------
func (this *Active) Schema() *schema.Schema {
	sch, _ := schema.Parse(this)
	return sch
}

func (this *Active) Clone() any {
	r := *this
	return &r
}

func (this *Active) Upsert(u *updater.Updater, op *operator.Operator) bool {
	return true
}

func (this *Active) Getter(u *updater.Updater, coll *dataset.Collection, keys []string) error {
	tx := db.Omit("uid", "update")
	if len(keys) > 0 {
		tx = tx.Where("_id IN ?", keys)
	} else {
		return errors.New("Active keys is empty")
		//tx = tx.Where("expire = ? OR expire >= ?", int64(0), u.Unix())
	}

	var rows []*Active
	if tx = tx.Find(&rows); tx.Error != nil {
		return tx.Error
	}
	for _, v := range rows {
		coll.Receive(v.OID, v)
	}
	return nil
}
func (this *Active) Setter(u *updater.Updater, bw dataset.BulkWrite) error {
	return bw.Submit()
}

func (this *Active) BulkWrite(u *updater.Updater) dataset.BulkWrite {
	bw := NewBulkWrite(this)
	return bw
}
func (this *Active) BulkWriteFilter(up update.Update) {
	if !up.Has(update.UpdateTypeSet, "update") {
		this.Update = time.Now().Unix()
		up.Set("update", this.Update)
	}
}
